from python_baway.common.xcommon import sep
from python_baway.exercise.oop.ppt17_page34_person import Person
from python_baway.exercise.oop.ppt17_page34_person import Student

"""
to-do: add comments
"""


class PersonShoot(Person):

    def __init__(self, name, gun='AK', bullet=0):
        self.set_name(name)
        self.set_province('HK')
        self.__gun = gun
        self.__bullet = bullet

    def __del__(self):
        super().__del__()
        print(f'Destructing PersonShoot {self._Person__name}')

    def __str__(self):
        return super().__str__() \
               + f'\n{{ PersonShoot: gun={self.__gun} bullet(s)={self.__bullet} }}'

    def set_gun(self, gun):
        self.__gun = gun

    def get_gun(self):
        return self.__gun

    def add_bullet(self, n):
        ori = self.__bullet
        self.__bullet += n
        print(f'{self._Person__name} got {n} bullets(s). Original bullet(s): {ori}. Bullet(s) total: {self.__bullet}')

    def shoot(self, n=1):
        if n < 1:
            print('Invalid parameter:', n)
            return
        if self.__bullet < n:
            print(self.get_name(), ' has no more than ', n, ' bullet(s). Cannot shoot!')
            return
        self.__bullet -= n
        print(self.get_name(), ' shot ', n, ' bullet(s). Rest bullet(s): ', self.__bullet, sep='')


if '__main__' == __name__:
    sep(label='xiaoyi')
    xiaoyi = PersonShoot('小一')
    print(xiaoyi)
    xiaoyi.add_bullet(5)
    for i in range(7):
        xiaoyi.shoot(1)
    xiaoyi.add_bullet(10)
    xiaoyi.shoot(100)
    xiaoyi.shoot(7)
    xiaoyi.shoot(0)
    xiaoyi.shoot(-2)
    xiaoyi.shoot(2)
    xiaoyi.shoot(100)
    xiaoyi._PersonShoot__bullet += 200
    xiaoyi.shoot(100)
    print(xiaoyi.__class__)
    print(xiaoyi)
    sep(label='End of testing PersonShoot')


class Hero(PersonShoot, Student):

    def __init__(self, name, skill):
        PersonShoot.__init__(self, name)
        Student.__init__(self, '999999', 'Student: ' + str(name))
        self.__skill = skill

    def __del__(self):
        PersonShoot.__del__(self)
        Student.__del__(self)
        print(f'Destructing Hero {self._Person__name} with skill {self.__skill}')

    def __str__(self):
        return PersonShoot.__str__(self) \
                + '\n' + Student.__str__(self) \
                + f'\n{{ Hero: skill={self.__skill} }}'

    def shoot(self):
        self.__neigong()
        count = 1000
        self.add_bullet(count)
        PersonShoot.shoot(self, count)
        print(f'Hero {self._Person__name} is shooting with unlimited bullets! This is called "{self.__skill}"')

    def __neigong(self):
        print(f'Hero "{self._Person__name}" is using his Nei Gong ...')


if '__main__' == __name__:
    sep(label='lvbu')
    lvbu = Hero('吕布', '舞弄方天画戟')
    print(lvbu)
    lvbu.shoot()
    PersonShoot.shoot(lvbu, 10)
    lvbu._Hero__neigong()
    lvbu.set_scores('Fighting', 99.99)
    lvbu.set_scores('Math', 60)
    lvbu.set_scores('Language', 59.99)
    print(lvbu.get_scores())
    print('In fact, his student name is "{}"'.format(lvbu._Student__name))
    print(lvbu)


    def check_types(obj):
        sep(label=obj.get_name())
        print('Person:', isinstance(obj, Person))
        print('PersonShoot', isinstance(obj, PersonShoot))
        print('Student', isinstance(obj, Student))
        print('Hero', isinstance(obj, Hero))

    check_types(lvbu)
    check_types(xiaoyi)


    def check_sub(cls):
        sep(label=repr(cls))
        print('object:', issubclass(cls, object))
        print('Person:', issubclass(cls, Person))
        print('PersonShoot:', issubclass(cls, PersonShoot))
        print('Student:', issubclass(cls, Student))
        print('Hero:', issubclass(cls, Hero))
        print('Person, Student:', issubclass(cls, (Person, Student)))


    check_sub(Hero)
    check_sub(PersonShoot)
    check_sub(Person)
    check_sub(Student)
    check_sub(object)

    sep(label='End of testing Hero')
